using System;
using System.Globalization;
using System.Text;

namespace flickr.api
{
    public struct FlickrParameterType
    {
        public readonly string Name;
        public readonly Type Type;
        private FlickrParameterType(string name) : this(name, typeof(string)) {}
        private FlickrParameterType(string name, Type type)
        {
            Name = name;
            Type = type;
        }
        
        public static readonly FlickrParameterType PhotoId = new FlickrParameterType("photo_id", typeof(Int32));
        public static readonly FlickrParameterType GroupId = new FlickrParameterType("group_id", typeof(Int32));
        public static readonly FlickrParameterType Count = new FlickrParameterType("count", typeof(Int32));
        public static readonly FlickrParameterType Tags = new FlickrParameterType("tags");
        public static readonly FlickrParameterType Frob = new FlickrParameterType("frob");

        public static readonly FlickrParameterType JustFriends = new FlickrParameterType("just_friends", typeof(bool));
        public static readonly FlickrParameterType IncludeSelf = new FlickrParameterType("include_self", typeof(bool));
        public static readonly FlickrParameterType SinglePhoto = new FlickrParameterType("single_photo", typeof(bool));
        public static readonly FlickrParameterType Extras = new FlickrParameterType("extras");
        public static readonly FlickrParameterType Dates = new FlickrParameterType("dates", typeof(DateTime[]));
        public static readonly FlickrParameterType DatesTaken = new FlickrParameterType("dates_taken", typeof(DateTime[]));
        public static readonly FlickrParameterType UserId = new FlickrParameterType("user_id");

        public static readonly FlickrParameterType Page = new FlickrParameterType("page", typeof(Int32));
        public static readonly FlickrParameterType PerPage = new FlickrParameterType("per_page", typeof(Int32));
        
        public static readonly FlickrParameterType TagMode = new FlickrParameterType("tag_mode");
        public static readonly FlickrParameterType Text = new FlickrParameterType("text");

        public static readonly FlickrParameterType MinUploadDate = new FlickrParameterType("min_upload_date", typeof(DateTime));
        public static readonly FlickrParameterType MaxUploadDate = new FlickrParameterType("max_upload_date", typeof(DateTime));
        public static readonly FlickrParameterType MinTakenDate = new FlickrParameterType("min_taken_date", typeof(DateTime));
        public static readonly FlickrParameterType MaxTakenDate = new FlickrParameterType("max_taken_date", typeof(DateTime));
        public static readonly FlickrParameterType License = new FlickrParameterType("license");
        public static readonly FlickrParameterType Sort = new FlickrParameterType("sort");

        public static readonly FlickrParameterType Method = new FlickrParameterType("method");
        public static readonly FlickrParameterType ApiKey = new FlickrParameterType("api_key");
        public static readonly FlickrParameterType ApiSignature = new FlickrParameterType("api_sig");
        public static readonly FlickrParameterType AuthToken = new FlickrParameterType("auth_token");

        public static readonly FlickrParameterType Nsid = new FlickrParameterType("nsid");
        public static readonly FlickrParameterType BlogId = new FlickrParameterType("blog_id");
        public static readonly FlickrParameterType BlogPassword = new FlickrParameterType("blog_password");
        public static readonly FlickrParameterType Title = new FlickrParameterType("title");
        public static readonly FlickrParameterType Description = new FlickrParameterType("description");
        public static readonly FlickrParameterType Secret = new FlickrParameterType("secret");

        public static readonly FlickrParameterType Email = new FlickrParameterType("find_email");
        public static readonly FlickrParameterType UserName = new FlickrParameterType("username");

        public static readonly FlickrParameterType PrivacyFilter = new FlickrParameterType("privacy_filter");

        public static readonly FlickrParameterType TagId = new FlickrParameterType("tag_id");

        public static readonly FlickrParameterType DatePosted = new FlickrParameterType("date_posted");
        public static readonly FlickrParameterType DateTaken = new FlickrParameterType("date_taken");
        public static readonly FlickrParameterType DateTakenGranularity = new FlickrParameterType("date_taken_granularity");

        public static readonly FlickrParameterType IsPublic = new FlickrParameterType("is_public", typeof(bool));
        public static readonly FlickrParameterType IsFriend = new FlickrParameterType("is_friend", typeof(bool));
        public static readonly FlickrParameterType IsFamily = new FlickrParameterType("is_family", typeof(bool));
        
        public static readonly FlickrParameterType PermComment = new FlickrParameterType("perm_comment");
        public static readonly FlickrParameterType PermAddMeta = new FlickrParameterType("perm_addmeta");

        public static readonly FlickrParameterType CategoryId = new FlickrParameterType("cat_id");

        public static readonly FlickrParameterType Filter = new FlickrParameterType("filter");
     
        public static readonly FlickrParameterType NoteX = new FlickrParameterType("note_x");
        public static readonly FlickrParameterType NoteY = new FlickrParameterType("note_y");
        public static readonly FlickrParameterType NoteW = new FlickrParameterType("note_w");
        public static readonly FlickrParameterType NoteH = new FlickrParameterType("note_h");
        public static readonly FlickrParameterType NoteText = new FlickrParameterType("note_text");
        public static readonly FlickrParameterType NoteId = new FlickrParameterType("note_id");

        public static readonly FlickrParameterType LicenseId = new FlickrParameterType("license_id");

        public static readonly FlickrParameterType PhotoSetId = new FlickrParameterType("photoset_id");
        public static readonly FlickrParameterType PhotoSetIds = new FlickrParameterType("photoset_ids");
        public static readonly FlickrParameterType PrimaryPhotoId = new FlickrParameterType("primary_photo_id");

        public static readonly FlickrParameterType PhotoIds = new FlickrParameterType("photo_ids");

        public static readonly FlickrParameterType Tag = new FlickrParameterType("tag");

        public static readonly FlickrParameterType URL = new FlickrParameterType("url");
    }
    
    public class FlickrParameter
    {

        private FlickrParameterType parameter;
        private string _value;
        
        public FlickrParameter(FlickrParameterType paramType)
        {
            parameter = paramType;
        }
        
        public string Name
        {
            get { return parameter.Name; }
        }
        
        public string Value
        {
            get { return _value; }
        }

        public FlickrParameter SetValue(string value)
        {
            _value = value;
            return this;
        }

        public FlickrParameter SetValue(DateTime value)
        {
            if (value != DateTime.MinValue)
            {
                return SetValue(value.ToString("yyyy-MM-dd hh:mm:ss", DateTimeFormatInfo.InvariantInfo));
            }
            return null;
        }

        public FlickrParameter SetValue(int value)
        {
            if (value != int.MinValue)
            {
                return SetValue(value.ToString());
            }
            return null;
        }

        public FlickrParameter SetValue(long value)
        {
            if (value != long.MinValue)
            {
                return SetValue(value.ToString());
            }
            return null;
        }

        public FlickrParameter SetValue(bool value)
        {
            return SetValue(value ? "1" : "0");
        }

        public FlickrParameter SetValue(string[] values)
        {
            StringBuilder concatedParameter = new StringBuilder();
            foreach (string value in values)
            {
                concatedParameter.AppendFormat("{0},", value);
            }
            return SetValue(concatedParameter.ToString().Substring(0, concatedParameter.Length - 1));
        }
    }
}